﻿using System.Web.Mvc;
using Orchard;
using Orchard.ContentManagement;
using Orchard.Localization;
using Contrib.Chapters.Models;
using Contrib.Chapters.Services;
using Orchard.UI.Admin;

namespace Contrib.Chapters.Controllers {
    
    [ValidateInput(false)]
    [Admin]
    public class BookAdminController : Controller, IUpdateModel {
        private readonly IChapterService _chapterService;

        public BookAdminController(IOrchardServices services, IChapterService chapterService) {
            Services = services;
            _chapterService = chapterService;
            T = NullLocalizer.Instance;
        }

        public IOrchardServices Services { get; set; }
        
        public Localizer T { get; set; }

        public ActionResult Index() {
            var books = _chapterService.GetBooks();
            return View(books);
        }

        public ActionResult Create() {
            if (!Services.Authorizer.Authorize(Permissions.ManageChapters, T("Couldn't create Book")))
                return new HttpUnauthorizedResult();

            var book = Services.ContentManager.New<BookPart>("Book");
            var model = Services.ContentManager.BuildEditor(book);

            return View((object)model);
        }

        [HttpPost, ActionName("Create")]
        public ActionResult CreatePOST() {
            if (!Services.Authorizer.Authorize(Permissions.ManageChapters, T("Couldn't create book")))
                return new HttpUnauthorizedResult();

            var book = Services.ContentManager.New<BookPart>("Book");
            var model = Services.ContentManager.UpdateEditor(book.ContentItem, this);

            if (_chapterService.GetBookByName(book.Name) != null) {
                ModelState.AddModelError("Title", T("A book with the same name already exists").ToString());
            }

            if (!ModelState.IsValid) {
                Services.TransactionManager.Cancel();
                return View(model);
            }

            Services.ContentManager.Create(book, VersionOptions.Published);
            _chapterService.CreateChapterContentType(book);

            return RedirectToAction("Index");
        }

        public ActionResult Edit(int id) {
            if (!Services.Authorizer.Authorize(Permissions.ManageChapters, T("Couldn't edit book")))
                return new HttpUnauthorizedResult();

            var book = _chapterService.GetBook(id);
            if (book == null) {
                return HttpNotFound();
            }

            var model = Services.ContentManager.BuildEditor(book);

            return View((object)model);
        }

        [HttpPost, ActionName("Edit")]
        public ActionResult EditPOST(int id) {
            if (!Services.Authorizer.Authorize(Permissions.ManageChapters, T("Couldn't edit book")))
                return new HttpUnauthorizedResult();

            var book = _chapterService.GetBook(id);
            var model = Services.ContentManager.UpdateEditor(book.ContentItem, this);

            if (!ModelState.IsValid) {
                Services.TransactionManager.Cancel();
                return View(model);
            }

            _chapterService.EditBook(book, (string)model.Name);

            return RedirectToAction("Index");
        }

        public ActionResult Delete(int id) {
            if (!Services.Authorizer.Authorize(Permissions.ManageChapters, T("Couldn't delete book")))
                return new HttpUnauthorizedResult();

            var book = _chapterService.GetBook(id);
            if (book == null) {
                return HttpNotFound();
            }

            _chapterService.DeleteBook(book);

            return RedirectToAction("Index");
        }


        bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {
            return TryUpdateModel(model, prefix, includeProperties, excludeProperties);
        }

        void IUpdateModel.AddModelError(string key, LocalizedString errorMessage) {
            ModelState.AddModelError(key, errorMessage.ToString());
        }
    }
}
